package com.campus.controller;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.campus.common.config.CodeConfig;
import com.campus.entity.Clazz.Clazz;
import com.campus.entity.File.FileUpload;
import com.campus.entity.ResultBody;
import com.campus.entity.vo.File.FileUploadClazzVO;
import com.campus.entity.vo.File.FileUploadVO;
import com.campus.service.ClazzService;
import com.campus.service.FileUploadService;
import com.campus.service.UploadService;
import com.campus.util.CopyPropertiesUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Author: AlaskaBoo
 * @Date: 2022-10-01 12:26
 **/
@RestController
@RequestMapping("/api/file")
@Transactional
public class FileUploadController {
    @Autowired
    private ClazzService clazzService;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private FileUploadService fileUploadService;
    @Value("${qiniu.prefix}")
    private String prefix;

    /**
     * 文件上传
     *
     * @param multipartFile
     * @param remark
     * @param fileType
     * @return
     */
    @PostMapping("/upload")
    @CacheEvict(value = "FileUpload", allEntries =true)
    public ResultBody upload(@RequestParam("file") MultipartFile multipartFile, String remark, String fileType,String clazzName) {
        //获取原始文件名
        String originalFilename = multipartFile.getOriginalFilename();
        int lastIndexOf = originalFilename.lastIndexOf(".");
        long fileSize = multipartFile.getSize();
        //获取文件后缀
        String suffix = originalFilename.substring(lastIndexOf + 1);
        //使用UUID随机产生文件名称，防止同名文件覆盖
        String uuid = UUID.randomUUID().toString();
        String newFileName = uuid + "." + suffix;
        try {
            uploadService.upload2Qiniu(multipartFile.getBytes(), newFileName);
            String url = prefix + "/" + newFileName;
            FileUpload file = new FileUpload();
            //数据落库
            file.setFileType(fileType);
            file.setClazzName(clazzName);
            file.setUuidName(newFileName);
            file.setUploadTime(new Date());
            file.setOldFilename(originalFilename);
            file.setSize(fileSize);
            file.setPath(url);
            file.setType(suffix);
            file.setIsShow(0);
            file.setRemark(remark);
            fileUploadService.save(file);
            FileUploadVO fileUploadVO = new FileUploadVO();
            BeanUtil.copyProperties(file, fileUploadVO);

            return ResultBody.ok().data("file", fileUploadVO).message(CodeConfig.PIC_UPLOAD_SUCCESS.message);
        } catch (Exception e) {
            e.printStackTrace();
            //图片上传失败
            return ResultBody.error().message(CodeConfig.PIC_UPLOAD_FAIL.message);
        }
    }


    /**
     * 删除荣誉图片
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    @CacheEvict(value = "FileUpload", allEntries =true)
    public ResultBody deleteImg(@PathVariable Long id) {
        FileUpload fileUpload = fileUploadService.lambdaQuery().in(FileUpload::getId, id).one();
        String uuidName = fileUpload.getUuidName();
        uploadService.delete2FileFromQiniu(uuidName);
        fileUploadService.removeById(id);
        return ResultBody.ok().data("id", id).message(CodeConfig.PIC_DELETE_FAIL.message);
    }

    /**
     * 文件修改
     *
     * @param multipartFile
     * @param fileUpload
     * @return
     */
    @PutMapping
    @CacheEvict(value = "FileUpload", allEntries =true)
    public ResultBody uploadByUpdate(MultipartFile multipartFile, FileUpload fileUpload) {
        if (multipartFile != null) {
            String originalFilename = multipartFile.getOriginalFilename();
            int lastIndexOf = originalFilename.lastIndexOf(".");
            long fileSize = multipartFile.getSize();
            //获取文件后缀
            String suffix = originalFilename.substring(lastIndexOf + 1);
            //使用UUID随机产生文件名称，防止同名文件覆盖
            String uuid = UUID.randomUUID().toString();
            String newFileName = uuid + "." + suffix;
            try {
                uploadService.upload2Qiniu(multipartFile.getBytes(), newFileName);
                String url = prefix + "/" + newFileName;
                //数据落库
                fileUpload.setUuidName(newFileName);
                fileUpload.setOldFilename(originalFilename);
                fileUpload.setSize(fileSize);
                fileUpload.setPath(url);
                fileUpload.setType(suffix);
                fileUploadService.updateById(fileUpload);
                Integer id = fileUpload.getId();
                FileUpload byId = fileUploadService.getById(id);
                FileUploadVO fileUploadVO = new FileUploadVO();
                BeanUtil.copyProperties(byId, fileUploadVO);
                return ResultBody.ok().data("fileUpload", fileUploadVO).message(CodeConfig.PIC_UPLOAD_SUCCESS.message);
            } catch (Exception e) {
                e.printStackTrace();
                //图片上传失败
                return ResultBody.error().message(CodeConfig.PIC_UPLOAD_FAIL.message);
            }
        }
        fileUploadService.updateById(fileUpload);
        Integer id = fileUpload.getId();
        FileUpload byId = fileUploadService.getById(id);
        FileUploadVO fileUploadVO = new FileUploadVO();
        BeanUtil.copyProperties(byId, fileUploadVO);
        return ResultBody.ok().data("fileUpload", fileUploadVO);
    }

    /**
     * 模糊查询
     *
     * @param currentPage
     * @param pageSize
     * @param fileUpload
     * @return
     */
    @GetMapping("/{currentPage}/{pageSize}")
    @Cacheable(value = "FileUpload")
    public ResultBody getClazz(@PathVariable("currentPage") Integer currentPage, @PathVariable("pageSize") Integer pageSize, FileUpload fileUpload) {
        //分页信息封装Page对象
        Page<FileUpload> page = new Page<>(currentPage, pageSize);
        //进行查询
        IPage<FileUploadVO> fileUploadInfo = fileUploadService.getFileUploadPage(page, fileUpload);
        //如果当前页码值大于了总页码值，那么重新执行查询操作，使用最大页码值作为当前页码值
        if (fileUploadInfo.getTotal() > 0) {
            return ResultBody.ok().data("fileUploadInfo", fileUploadInfo).message(CodeConfig.QUERY_SUCCESS.message);
        }
        return ResultBody.error().message(CodeConfig.QUERY_FAIL.message);
    }

    /**
     * 班级普通文件查询
     *
     * @param clazzNum
     * @return
     */
    @GetMapping("/clazzName/getClazzHonors")
    @Cacheable(value = "FileUpload")
    public ResultBody getClazzHonors(Integer clazzNum) {
        if (clazzNum == null) {
            return ResultBody.error(CodeConfig.QUERY_FAIL);
        }
        // 查询全表
        List<Clazz> clazzList = clazzService.lambdaQuery().eq(true,Clazz::getClassNum, clazzNum).list();
        return lambdaQueryClazz(clazzList);
    }

    private ResultBody lambdaQueryClazz(@NotNull List<Clazz> clazzList) {
        List<FileUploadClazzVO> list = new ArrayList<>();
        clazzList.forEach(clazz1 -> {
            FileUploadClazzVO fileUploadClazzVO = new FileUploadClazzVO();
            BeanUtil.copyProperties(clazz1, fileUploadClazzVO);
            List<FileUpload> fileUploadList = fileUploadService
                    .list(new QueryWrapper<FileUpload>()
                            .inSql("id", "select id from t_file_upload where clazz_name=" + clazz1.getClassNum()));
            List<FileUploadVO> collect = fileUploadList.stream().map(fileUpload -> CopyPropertiesUtils.copyProperties(fileUpload, FileUploadVO.class)).collect(Collectors.toList());
            fileUploadClazzVO.setFileUploadList(collect);
            list.add(fileUploadClazzVO);
        });
        return ResultBody.ok().data("clazzList", list).message(CodeConfig.QUERY_SUCCESS.message);
    }

}
